package cn.lili.listener;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.ThreadPoolUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.modules.distribution.client.DistributionGoodsClient;
import cn.lili.modules.distribution.client.DistributionSelectedGoodsClient;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.distribution.entity.dto.DistributionGoodsSearchParams;
import cn.lili.modules.file.client.UploadClient;
import cn.lili.modules.file.util.FileUtil;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GoodsCollectionClient;
import cn.lili.modules.goods.client.GoodsIndexClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsGallery;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsMarketEnum;
import cn.lili.modules.member.client.FootPrintClient;
import cn.lili.modules.member.entity.dos.FootPrint;
import cn.lili.modules.member.entity.dos.MemberEvaluation;
import cn.lili.modules.page.entity.dos.PageData;
import cn.lili.modules.promotion.client.PromotionGoodsClient;
import cn.lili.modules.promotion.entity.dos.BaseStandardPromotions;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.search.PromotionGoodsSearchParams;
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.entity.dos.EsSupplierGoodsIndex;
import cn.lili.modules.search.entity.dto.EsDeleteDTO;
import cn.lili.modules.search.entity.dto.EsGoodsIndexUpdateDTO;
import cn.lili.modules.search.entity.dto.EsGoodsIndexUpdatePromotionsDTO;
import cn.lili.modules.store.client.StoreClient;
import cn.lili.modules.store.entity.vos.StoreVO;
import cn.lili.modules.system.client.GoodsAuthClient;
import cn.lili.modules.system.client.PageDataClient;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.GoodsAuthOpenCallback;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.GoodsSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.routing.GoodsRoutingKey;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 商品消息
 *
 * @author paulG
 * @since 2020/12/9
 **/
@Component
@Slf4j
@RequiredArgsConstructor
public class GoodsMessageListener {

    private final GoodsClient goodsClient;

    private final GoodsIndexClient goodsIndexClient;

    private final FootPrintClient footPrintClient;

    private final GoodsCollectionClient goodsCollectionClient;

    private final List<GoodsCommentCompleteEvent> goodsCommentCompleteEvents;

    private final DistributionGoodsClient distributionGoodsClient;

    private final DistributionSelectedGoodsClient distributionSelectedGoodsClient;

    private final PromotionGoodsClient promotionGoodsClient;

    private final StoreClient storeClient;

    private final UploadClient uploadClient;

    private final SettingClient settingClient;

    private final PageDataClient pageDataClient;

    private final GoodsAuthClient goodsAuthClient;


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.VIEW_GOODS),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.VIEW_GOODS))
    public void viewGoods(FootPrint footPrint) {
        footPrintClient.saveFootprint(footPrint);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GENERATOR_GOODS_INDEX),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GENERATOR_GOODS_INDEX))
    public void generatorGoodsIndex(List<String> goodsIdsList) {

//        try {
//            log.info("生成索引: {}", goodsIdsList);
//
//            List<Goods> goodsList = this.goodsClient.queryListByParams(
//                    GoodsSearchParams.builder()
//                            .marketEnable(GoodsMarketEnum.UPPER.name())
//                            .authFlag(GoodsAuthEnum.PASS.name())
//                            .ids(Arrays.asList(goodsIdsList.split(","))).build());
//            this.updateGoodsIndex(goodsList);
//
//        } catch (Exception e) {
//            log.error("生成商品索引事件执行异常，商品信息: " + goodsIdsList, e);
//        }

        /**
         * 上面注释掉的是原有处理逻辑
         * 以下为新的处理逻辑
         */
        try {
            log.info("生成索引: {}", goodsIdsList);
//            List<Goods> goodsList = this.goodsClient.queryListByParams(
//                    GoodsSearchParams.builder()
//                            .ids(Arrays.asList(goodsIdsList.split(","))).build());
            List<Goods> goodsList = this.goodsClient.queryListByParams(
                    GoodsSearchParams.builder()
                            .ids(goodsIdsList).build());
            if(null!=goodsList && !goodsList.isEmpty()){
                List<Goods> updateIndexGoodsList = new ArrayList<>(); //待更新的商品索引
                List<Goods> delIndexGoodsList = new ArrayList<>(); //待删除的商品索引
                goodsList.forEach(goods -> {
                    if(goods.getMarketEnable().equals(GoodsMarketEnum.UPPER.name())
                            && goods.getAuthFlag().equals(GoodsAuthEnum.PASS.name())){
                        updateIndexGoodsList.add(goods);
                    }else{
                        delIndexGoodsList.add(goods);
                    }
                });
                if(updateIndexGoodsList.size()>0){
                    this.updateGoodsIndex(updateIndexGoodsList);
                    //异步-商品授权变动通知
                    updateIndexGoodsList.forEach(goods->{
                        GoodsAuthOpenCallback goodsAuthOpenCallback = new GoodsAuthOpenCallback();
                        goodsAuthOpenCallback.setGoodsId(goods.getId());
                        ThreadPoolUtil.getPool().execute(()->goodsAuthClient.callBackGoods(goodsAuthOpenCallback));
                    });
                }


                if(delIndexGoodsList.size()>0){
                    delIndexGoodsList.forEach(goods->{
                        EsDeleteDTO esDeleteDTO = new EsDeleteDTO();
                        Map<String, Object> queryFields = new HashMap<>();
                        queryFields.put("goodsId",goods.getId());
                        esDeleteDTO.setQueryFields(queryFields);
                        if(goods.getScene().equals(SceneEnums.STORE.name())){
                            esDeleteDTO.setClazz(EsGoodsIndex.class);
                            this.goodsIndexClient.deleteIndex(esDeleteDTO);
                        }else if(goods.getScene().equals(SceneEnums.SUPPLIER.name())){
                            esDeleteDTO.setClazz(EsSupplierGoodsIndex.class);
                            this.goodsIndexClient.deleteIndex(esDeleteDTO);
                        }
                    });
                }
            }
        } catch (Exception e) {
            log.error("生成商品索引事件执行异常，商品信息: " + goodsIdsList, e);
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GENERATOR_STORE_GOODS_INDEX),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GENERATOR_STORE_GOODS_INDEX))
    public void generatorStoreGoodsIndex(String storeId) {
        try {
            this.updateGoodsIndex(storeId);
        } catch (Exception e) {
            log.error("生成店铺商品索引事件执行异常，店铺ID: " + storeId, e);
        }
    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.UPDATE_GOODS_INDEX_PROMOTIONS),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.UPDATE_GOODS_INDEX_PROMOTIONS))
    public void updateGoodsIndexPromotion(JSONObject jsonObject) {
        try {
            updateGoodsIndexPromotions(jsonObject);
        } catch (Exception e) {
            log.error("重置商品促销: " + jsonObject.toString(), e);
        }
    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.DELETE_GOODS_INDEX_PROMOTIONS),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.DELETE_GOODS_INDEX_PROMOTIONS))
    public void deleteGoodsIndexPromotion(JSONObject jsonObject) {
        String promotionKey = jsonObject.getStr("promotionKey");
        if (CharSequenceUtil.isEmpty(promotionKey)) {
            return;
        }
        if (CharSequenceUtil.isNotEmpty(jsonObject.getStr("scopeId"))) {
            this.goodsIndexClient.deleteEsGoodsPromotionByPromotionKey(Arrays.asList(jsonObject.getStr("scopeId").split(",")), promotionKey);
        } else {
            this.goodsIndexClient.deleteEsGoodsPromotionByPromotionKey(promotionKey);
        }

    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.UPDATE_GOODS_INDEX),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.UPDATE_GOODS_INDEX))
    public void updateGoodsIndexListener(String goodsIdStr) {
        try {
            GoodsSearchParams searchParams = new GoodsSearchParams();
            searchParams.setId(ArrayUtil.join(JSONUtil.toList(goodsIdStr, String.class).toArray(), ","));
            List<Goods> goodsList = goodsClient.queryListByParams(searchParams);
            this.updateGoodsIndex(goodsList);


        } catch (Exception e) {
            log.error("更新商品索引事件执行异常，商品信息: " + goodsIdStr, e);
        }

    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.UPDATE_GOODS_INDEX_FIELD),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.UPDATE_GOODS_INDEX_FIELD))
    public void updateGoodsIndexField(String updateIndexFieldsJsonStr) {
        try {
            log.info("===========更新 goodsIndex =="+updateIndexFieldsJsonStr);
            JSONObject updateIndexFields = JSONUtil.parseObj(updateIndexFieldsJsonStr);
            @SuppressWarnings("unchecked")
            Map<String, Object> queryFields = updateIndexFields.get("queryFields", Map.class);
            @SuppressWarnings("unchecked")
            Map<String, Object> updateFields = updateIndexFields.get("updateFields", Map.class);
            goodsIndexClient.updateIndexField(new EsGoodsIndexUpdateDTO(queryFields, updateFields));
        } catch (Exception e) {
            log.error("更新商品索引事件执行异常，商品信息: " + updateIndexFieldsJsonStr, e);
        }

    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GOODS_DELETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GOODS_DELETE))
    public void goodsDelete(List<String> goodsIds) {

        try {
            for (String goodsId : goodsIds) {
                Goods goodsById = this.goodsClient.getById(goodsId);
                log.info("==================删除代理供应商商品=="+JSON.toJSONString(goodsById));
                if (goodsById != null) {
                    this.deleteGoods(goodsById);
                    goodsIndexClient.deleteIndex(
                            EsDeleteDTO.builder()
                                    .queryFields(MapUtil.builder(new HashMap<String, Object>()).put("goodsId", goodsId).build())
                                    .clazz(SceneEnums.SUPPLIER.name().equals(goodsById.getScene()) ? EsSupplierGoodsIndex.class : EsGoodsIndex.class)
                                    .build());

                }
                //如果删除的是供应商的商品，则需要再删除所有店铺代理过的商品
                if(SceneEnums.SUPPLIER.name().equals(goodsById.getScene())){

                    List<Goods> goodsList = goodsClient.getProxyGoodsList(goodsById.getStoreId(),goodsById.getId());
                    log.info("==================删除代理供应商商品=="+goodsList.size());
                    if(null!=goodsList && !goodsList.isEmpty()){
                        goodsList.forEach(proxyGoods->{
                            goodsIndexClient.deleteIndex(
                                    EsDeleteDTO.builder()
                                            .queryFields(MapUtil.builder(new HashMap<String, Object>()).put("goodsId", proxyGoods.getId()).build())
                                            .clazz(EsGoodsIndex.class)
                                            .build());
                        });

                    }
                }
                //异步-商品授权变动通知
                GoodsAuthOpenCallback goodsAuthOpenCallback = new GoodsAuthOpenCallback();
                goodsAuthOpenCallback.setGoodsId(goodsId);
                ThreadPoolUtil.getPool().execute(()->goodsAuthClient.callBackGoods(goodsAuthOpenCallback));
            }

        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("删除商品索引事件执行异常，商品信息id: " + goodsIds, e);
        }
    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.SKU_DELETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.SKU_DELETE))
    public void skuDelete(List<String> skuIds) {
        goodsCollectionClient.deleteSkuCollection(skuIds);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.STORE_GOODS_DELETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.STORE_GOODS_DELETE))
    public void storeGoodsDelete(String storeId) {
        try {
            StoreVO store = storeClient.getStore(storeId);
            if (store != null) {
                goodsIndexClient.deleteIndex(
                        EsDeleteDTO.builder()
                                .queryFields(MapUtil.builder(new HashMap<String, Object>()).put("storeId", storeId).build())
                                .clazz(SceneEnums.SUPPLIER.name().equals(store.getScene()) ? EsSupplierGoodsIndex.class : EsGoodsIndex.class)
                                .build());
            }


        } catch (Exception e) {
            log.error("删除店铺商品索引事件执行异常，商品信息: " + storeId, e);
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GOODS_COMMENT_COMPLETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GOODS_COMMENT_COMPLETE))
    public void goodsCommentComplete(MemberEvaluation memberEvaluation) {

        for (GoodsCommentCompleteEvent goodsCommentCompleteEvent : goodsCommentCompleteEvents) {
            try {
                goodsCommentCompleteEvent.goodsComment(memberEvaluation);
            } catch (Exception e) {
                log.error("评价{},在{}业务中，状态修改事件执行异常",
                        memberEvaluation.toString(),
                        goodsCommentCompleteEvent.getClass().getName(),
                        e);
            }
        }
    }


    /**
     * 商品采集完成后，转存商品相关图片到平台所用oss
     * @param goods
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GOODS_GRAB_COMPLETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GOODS_GRAB_COMPLETE))
    public void goodsGrabComplete(Goods goods) {

        List<GoodsGallery> galleryList = goodsClient.getGoodsGallery(goods.getId());
        if(null!=galleryList && galleryList.size()>0){
            galleryList.forEach(item->{
                String oriPath = item.getOriginal();
                String ossPath = uploadClient.upload(oriPath);
                if(null!=ossPath){
                    Setting setting = settingClient.get(SettingEnum.GOODS_SETTING.name());
                    GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
                    //缩略图
                    String thumbnail = FileUtil.getUrl(ossPath, goodsSetting.getAbbreviationPictureWidth(), goodsSetting.getAbbreviationPictureHeight());
                    //小图
                    String small = FileUtil.getUrl(ossPath, goodsSetting.getSmallPictureWidth(), goodsSetting.getSmallPictureHeight());
                    //赋值
                    item.setSmall(small);
                    item.setThumbnail(thumbnail);
                    item.setOriginal(ossPath);
                }
            });

            goodsClient.updateGoodsGallery(galleryList);
            //处理详情图片转换
            if(StringUtil.isNotEmpty(goods.getIntro())){
                List<String> imgList = getUrls(goods.getIntro());
                StringBuilder descContent = new StringBuilder();
                descContent.append("<p>");
                imgList.forEach(item-> {
                    String ossPath = uploadClient.upload(item);
                    if(null!=ossPath){
                        descContent.append("<img src=\""+ossPath+"\" />");
                    }
                });
                descContent.append("</p>");
                goods.setIntro(descContent.toString());
                goods.setOriginal(galleryList.get(0)!=null ? galleryList.get(0).getOriginal() : null);
                goods.setThumbnail(galleryList.get(0)!=null ?galleryList.get(0).getThumbnail(): null);
                goods.setSmall(galleryList.get(0)!=null ?galleryList.get(0).getSmall(): null);
                goodsClient.updateGoodsInfoImages(goods);
            }
        }


        //处理sku图片的转换
        GoodsSearchParams searchParams = new GoodsSearchParams();
        searchParams.setGoodsId(goods.getId());
        List<GoodsSku> skuList = goodsClient.getGoodsSkuByList(searchParams);
        if(null!=skuList && skuList.size()>0){
            skuList.forEach(item->{
                Map<String,Object> specMap  = JSON.parseObject(item.getSpecs(),Map.class);
                if(specMap.containsKey(GoodsSku.IMAGES_KEY)){
                    List<Map<String,String>> imgList = (List<Map<String, String>>)specMap.get(GoodsSku.IMAGES_KEY);
                    if(!imgList.isEmpty()){
                        Map<String,String> mm = imgList.get(0);
                        String url = mm.get("url");
                        String ossPath = uploadClient.upload(url);
                        if(null!=ossPath){
                            Setting setting = settingClient.get(SettingEnum.GOODS_SETTING.name());
                            GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
                            //缩略图
                            String thumbnail = FileUtil.getUrl(ossPath, goodsSetting.getAbbreviationPictureWidth(), goodsSetting.getAbbreviationPictureHeight());
                            //小图
                            String small = FileUtil.getUrl(ossPath, goodsSetting.getSmallPictureWidth(), goodsSetting.getSmallPictureHeight());
                            //赋值
                            item.setBig(ossPath);
                            item.setSmall(small);
                            item.setThumbnail(thumbnail);
                            mm.put("url",ossPath);
                            imgList.set(0,mm);
                            specMap.put(GoodsSku.IMAGES_KEY,imgList);
                            item.setSpecs(JSON.toJSONString(specMap));
                        }
                    }
                }
            });
            goodsClient.updateGoodsSkuImages(skuList);
        }

        if (StringUtil.isNotEmpty(goods.getGoodsVideo())) {
            String ossPath = uploadClient.upload(goods.getGoodsVideo());
            if(null!=ossPath){
                Setting setting = settingClient.get(SettingEnum.GOODS_SETTING.name());
                GoodsSetting goodsSetting = JSONUtil.toBean(setting.getSettingValue(), GoodsSetting.class);
                //缩略图
                String video = FileUtil.getUrl(ossPath, goodsSetting.getAbbreviationPictureWidth(), goodsSetting.getAbbreviationPictureHeight());
                goods.setGoodsVideo(video);
                goodsClient.updateVideoById(goods);
            }
        }

    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.BUY_GOODS_COMPLETE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.BUY_GOODS_COMPLETE))
    public void goodsBuyComplete(List<GoodsCompleteMessage> goodsCompleteMessageList) {

        for (GoodsCompleteMessage goodsCompleteMessage : goodsCompleteMessageList) {
            Goods goods = goodsClient.getById(goodsCompleteMessage.getGoodsId());
            if (goods != null) {
                //更新商品购买数量
                if (goods.getBuyCount() == null) {
                    goods.setBuyCount(0);
                }
                int buyCount = goods.getBuyCount() + goodsCompleteMessage.getBuyNum();
                goods.setBuyCount(buyCount);
                this.goodsClient.updateGoodsBuyCount(goodsCompleteMessage.getGoodsId(), buyCount);
            } else {
                log.error("商品Id为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在，更新商品失败！");
            }
            GoodsSku goodsSku = goodsClient.getGoodsSkuByIdFromCache(goodsCompleteMessage.getSkuId());
            if (goodsSku != null) {
                //更新商品购买数量
                if (goodsSku.getBuyCount() == null) {
                    goodsSku.setBuyCount(0);
                }
                int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
                goodsSku.setBuyCount(buyCount);
                goodsClient.updateGoodsSku(goodsSku);

//                this.goodsIndexClient.updateIndexField(
//                        new EsGoodsIndexUpdateDTO(
//                                MapUtil.builder(new HashMap<String, Object>()).put("id", goodsCompleteMessage.getSkuId()).build(),
//                                MapUtil.builder(new HashMap<String, Object>()).put("buyCount", goods.getBuyCount()).build()
//                        )
//                );

                //更新es中商品的已售数量，根据goodsId进行查找和更新
                this.goodsIndexClient.updateIndexField(
                        new EsGoodsIndexUpdateDTO(
                                MapUtil.builder(new HashMap<String, Object>()).put("goodsId", goodsCompleteMessage.getGoodsId()).build(),
                                MapUtil.builder(new HashMap<String, Object>()).put("buyCount", goods!=null?goods.getBuyCount():0).build()
                        )
                );

                //更新es中商品的已售数量，使用先删后增的操作
                //this.goodsIndexClient.updateGoodsIndexByGoodsList(Collections.singletonList(goods));


            } else {
                log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在，更新商品失败！");
            }
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.UPDATE_PAGE_DATA_GOODS),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.UPDATE_PAGE_DATA_GOODS))
    public void updatePageDataGoods(List<String> goodsIds) {
        try {
            for (String goodsId : goodsIds) {
                List<PageData> pageDataList = pageDataClient.getListByGoodsId(goodsId);
                if (!pageDataList.isEmpty()) {
                    for (PageData pageData : pageDataList) {
                        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(pageData.getPageData());
                        render(jsonObject, goodsId);
                        //String pageDataStr = analysisPageData(pageData.getPageData(), goodsId);
                        pageData.setPageData(jsonObject.toString());
                        pageDataClient.updateByPageData(pageData);
                    }
                }
            }
        } catch (Exception e) {
            log.error("更新装修商品数据异常，商品信息id: " + goodsIds, e);
        }
    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${lili.amqp.goods}" + "_" + GoodsRoutingKey.GOODS_CHANGE),
            exchange = @Exchange(value = "${lili.amqp.goods}"),
            key = GoodsRoutingKey.GOODS_CHANGE))
    public void goodsChange(String json) {

        log.info("商品发生变动，判断是否需要回调");
        /**
         *
         */

    }


    private void updateGoodsIndexPromotions(JSONObject jsonObject) {
        try {
            // 转换为详细的促销信息（注：促销信息必须继承自 BasePromotions，且必须保证派生类存在与sdk包下）
            BaseStandardPromotions promotions = (BaseStandardPromotions) jsonObject.get("promotions",
                    ClassLoaderUtil.loadClass(jsonObject.getStr("promotionsType")));
            // 获取促销唯一key,由 促销类型 + 促销id 组成
            String esPromotionKey = jsonObject.getStr("esPromotionKey");
            if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(promotions.getScopeType())) {
                PromotionGoodsSearchParams searchParams = new PromotionGoodsSearchParams();
                searchParams.setPromotionId(promotions.getId());
                List<PromotionGoods> promotionGoodsList = this.promotionGoodsClient.listFindAll(searchParams);
                List<String> skuIds = promotionGoodsList.stream().map(PromotionGoods::getSkuId).toList();
                // 更新商品索引促销信息（删除索引中原促销信息，更新索引中促销信息）
                this.goodsIndexClient.deleteEsGoodsPromotionByPromotionKey(skuIds, esPromotionKey);
                this.goodsIndexClient.updateEsGoodsIndexByList(new EsGoodsIndexUpdatePromotionsDTO(promotionGoodsList, jsonObject.toString()));
            } else if (PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name().equals(promotions.getScopeType())) {
                GoodsSearchParams searchParams = new GoodsSearchParams();
                searchParams.setCategoryPath(promotions.getScopeId());
                List<GoodsSku> goodsSkuByList = this.goodsClient.getGoodsSkuByList(searchParams);
                List<String> skuIds = goodsSkuByList.stream().map(GoodsSku::getId).toList();
                // 更新商品索引促销信息（删除索引中原促销信息，更新索引中促销信息）
                this.goodsIndexClient.deleteEsGoodsPromotionByPromotionKey(skuIds, esPromotionKey);
                this.goodsIndexClient.updateEsGoodsIndexPromotions(new EsGoodsIndexUpdatePromotionsDTO(jsonObject.toString(), skuIds));
            } else if (PromotionsScopeTypeEnum.ALL.name().equals(promotions.getScopeType())) {
                // 更新商品索引促销信息（删除索引中原促销信息，更新索引中促销信息）
                this.goodsIndexClient.updateEsGoodsIndexAllByList(new EsGoodsIndexUpdatePromotionsDTO(jsonObject.toString()));
            }
        } catch (Exception e) {
            log.error("生成商品索引促销信息执行异常", e);
        }
    }

    /**
     * 更新商品索引
     *
     * @param goodsList 商品列表消息
     */
    private void updateGoodsIndex(List<Goods> goodsList) {
        this.goodsIndexClient.updateGoodsIndexByGoodsList(goodsList);
    }


    /**
     * 更新商品索引根据店铺id
     *
     * @param storeId 店铺id
     */
    private void updateGoodsIndex(String storeId) {
        //如果商品通过审核&&并且已上架
        this.goodsIndexClient.updateGoodsIndexByStore(storeId);

    }

    /**
     * 删除商品
     * 1.更新店铺的商品数量
     * 2.删除分销员-分销商品绑定关系
     * 3.删除分销商品
     *
     * @param goods 消息
     */
    private void deleteGoods(Goods goods) {

        DistributionGoodsSearchParams searchParams = new DistributionGoodsSearchParams();
        searchParams.setGoodsId(goods.getId());
        //删除获取分销商品
        DistributionGoods distributionGoods = distributionGoodsClient.getDistributionGoods(searchParams);

        if (distributionGoods != null) {

            //删除分销商品绑定关系
            distributionSelectedGoodsClient.deleteByDistributionGoodsId(distributionGoods.getId());

            //删除分销商品
            distributionGoodsClient.removeById(distributionGoods.getId());
        }
    }



    private  List<String> getUrls(String str) {
        Pattern pattern = Pattern.compile("(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]");
//        String a = "[{\"element\":\"lbtEl\",\"name\":\"轮播图\",\"icon\":\"el-icon-data-board\",\"attribute\":{\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":0,\"marginRight\":0,\"imageList\":[{\"name\":\"image\",\"url\":\"https://paiqi-1.oss-cn-beijing.aliyuncs.com/paiqi/20220512/d5b886c221f64c15ae96632d41ca1bda.jpg\",\"height\":800,\"width\":750,\"uid\":1652326171322,\"status\":\"success\"},{\"name\":\"image\",\"url\":\"https://paiqi-1.oss-cn-beijing.aliyuncs.com/paiqi/20220512/5e82ceaad5444b1d8f315fce840d9035.jpg\",\"height\":800,\"width\":750,\"uid\":1652326180600,\"status\":\"success\"}],\"Time\":3}},{\"element\":\"imageEl\",\"name\":\"图片\",\"icon\":\"el-icon-picture-outline\",\"attribute\":{\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":0,\"marginRight\":0,\"image\":\"https://paiqi-1.oss-cn-beijing.aliyuncs.com/paiqi/20220512/c40ec60a89ce4c48b6972ac43e470c09.jpg\"}},{\"element\":\"videoEl\",\"name\":\"视频\",\"icon\":\"el-icon-video-camera\",\"attribute\":{\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":0,\"marginRight\":0,\"video\":\"https://paiqi-1.oss-cn-beijing.aliyuncs.com/paiqi/20220512/fbe7fc1335bd4dc7b8bca6c2693b5200.mp4\"}},{\"element\":\"textEl\",\"name\":\"文本\",\"icon\":\"el-icon-edit\",\"attribute\":{\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":0,\"marginRight\":0,\"content\":\"内容\"}},{\"element\":\"linkEl\",\"name\":\"分割线\",\"icon\":\"el-icon-tickets\",\"attribute\":{\"marginTop\":25,\"marginBottom\":25,\"marginLeft\":0,\"marginRight\":0,\"borderStyle\":\"solid\",\"borderWidth\":1,\"borderColor\":\"#000\",\"width\":100}},{\"element\":\"phoneEl\",\"name\":\"电话\",\"icon\":\"el-icon-phone-outline\",\"attribute\":{\"fontSize\":14,\"color\":\"#fff\",\"background\":\"#07C160\",\"content\":\"拨打电话\",\"btnWeight\":\"normal\",\"phone\":\"13332333333\"}},{\"element\":\"shopCardEl\",\"name\":\"商家名片\",\"icon\":\"el-icon-wallet\",\"attribute\":{\"name\":\"测试地址\",\"address\":\"四川国际大厦\",\"phone\":\"14444444444\",\"lat\":30.66068,\"lng\":104.071519,\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":80,\"marginRight\":0}},{\"element\":\"noticeEl\",\"name\":\"公告\",\"icon\":\"el-icon-takeaway-box\",\"attribute\":{\"direction\":\"left\",\"scrollamount\":3,\"marginTop\":0,\"marginBottom\":0,\"marginLeft\":0,\"marginRight\":0,\"color\":\"#000\",\"content\":\"公告的格式变化就是不回家的说不定还巴适得很不合适的\"}}]";
        Matcher matcher = pattern.matcher(str);
        List<String> urlArr = new ArrayList<>();
        while (matcher.find()) {
            urlArr.add(matcher.group());
        }
        return urlArr;
    }

    public String analysisPageData(String jsonStr, String goodsId) {
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
        if (jsonObject.containsKey("list")) {
            JSONArray listArray = jsonObject.getJSONArray("list");
            if (!listArray.isEmpty()) {
                for (Object object : listArray) {
                    com.alibaba.fastjson.JSONObject json = (com.alibaba.fastjson.JSONObject) object;
                    if (null != json && json.containsKey("options")) {
                        com.alibaba.fastjson.JSONObject options = json.getJSONObject("options");

                    }
                }
            }
        }

        return jsonObject.toString();
    }

    public static String analysisPageData2(String jsonStr, String goodsId) {
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(jsonStr);
        if (jsonObject.containsKey("list")) {
            JSONArray listArray = jsonObject.getJSONArray("list");
            if (!listArray.isEmpty()) {
                for (Object object : listArray) {
                    com.alibaba.fastjson.JSONObject json = (com.alibaba.fastjson.JSONObject) object;
                    if (null != json && json.containsKey("options")) {
                        com.alibaba.fastjson.JSONObject options = json.getJSONObject("options");
                        if (options.containsKey("list")) {
                            JSONArray optionsListArray = options.getJSONArray("list");
                            for (Object listObj : optionsListArray) {
                                com.alibaba.fastjson.JSONObject listJson = (com.alibaba.fastjson.JSONObject) listObj;
                                if (listJson.containsKey("goodsList")) {
                                    JSONArray goodsListArray = listJson.getJSONArray("goodsList");
                                    JSONArray newGoodsListArray = new JSONArray();
                                    for (Object goodsObj : goodsListArray) {
                                        com.alibaba.fastjson.JSONObject goodsJson = (com.alibaba.fastjson.JSONObject) goodsObj;
                                        if (goodsJson.containsKey("url") &&
                                                goodsJson.getString("url").contains(goodsId)) {
                                            continue;
                                        }
                                        newGoodsListArray.add(goodsJson);
                                    }
                                    listJson.put("goodsList", newGoodsListArray);
                                }else if (listJson.containsKey("listWay")) {
                                    JSONArray goodsListArray = listJson.getJSONArray("listWay");
                                    JSONArray newGoodsListArray = new JSONArray();
                                    for (Object goodsObj : goodsListArray) {
                                        com.alibaba.fastjson.JSONObject goodsJson = (com.alibaba.fastjson.JSONObject) goodsObj;
                                        if ((goodsJson.containsKey("goodsId") && goodsJson.getString("goodsId").contains(goodsId)) ||
                                                (goodsJson.containsKey("supplierGoodsId") && goodsJson.getString("supplierGoodsId").contains(goodsId))) {
                                            continue;
                                        }
                                        newGoodsListArray.add(goodsJson);
                                    }
                                    listJson.put("listWay", newGoodsListArray);
                                }else if (listJson.containsKey("url")) {
                                    com.alibaba.fastjson.JSONObject urlJson = (com.alibaba.fastjson.JSONObject) listObj;
                                    if (urlJson.containsKey("pageData")) {
                                        String pageData = urlJson.getString("pageData");
                                        String resultStr = analysisPageData2(pageData, goodsId);
                                        if (resultStr.contains(goodsId)) {
                                            resultStr = analysisPageData2(pageData, goodsId);
                                        }
                                        urlJson.put("pageData", resultStr);
                                    }
                                }
                            }
                        }
                        if (options.containsKey("left")) {
                            com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject("left");
                            removeGoods(goodsId, jsonObj);
                        }
                        if (options.containsKey("middle")) {
                            com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject("middle");
                            removeGoods(goodsId, jsonObj);
                        }
                        if (options.containsKey("right")) {
                            com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject("right");
                            removeGoods(goodsId, jsonObj);
                        }
                        if (options.containsKey("contentLeft")) {
                            com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject("contentLeft");
                            removeGoods(goodsId, jsonObj);
                        }
                        if (options.containsKey("contentRight")) {
                            com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject("contentRight");
                            removeGoods(goodsId, jsonObj);
                        }
                    }
                }
            }
        }

        return jsonObject.toString();
    }

    /*public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://100.116.29.48:3306/lilishop_system?characterEncoding=utf-8", "debug_r", "8hMCw9MfbAioBNHzaVNu");
        String sql = "select * from li_page_data where id = '1707220624075816960'";
        Statement state = conn.createStatement();
        ResultSet rs = state.executeQuery(sql);
        String str = "";
        while (rs.next()){
            str = rs.getString("page_data");
        }

        *//*String result = analysisPageData2(str, "1113");
        System.out.println(result);*//*

        com.alibaba.fastjson.JSONObject object = com.alibaba.fastjson.JSONObject.parseObject(str);
        render(object, "3050");
        System.out.println(object.toString());
    }*/

    private static void removeGoods(String str, com.alibaba.fastjson.JSONObject jsonObj) {
        if (jsonObj.containsKey("list")) {
            JSONArray listJsonArray = jsonObj.getJSONArray("list");
            JSONArray newListJsonArray = new JSONArray();
            for (Object obj : listJsonArray) {
                com.alibaba.fastjson.JSONObject goodsJson = (com.alibaba.fastjson.JSONObject) obj;
                if (goodsJson.containsKey("url") &&
                        goodsJson.getString("url").contains(str)) {
                    continue;
                }
                newListJsonArray.add(goodsJson);
            }
            jsonObj.put("list", newListJsonArray);
        }
    }

    private void render(com.alibaba.fastjson.JSONObject jsonObject, String goodsId){
        if (jsonObject.containsKey("list")) {
            for(int i = 0; i < jsonObject.getJSONArray("list").size(); i++) {
                renderItem(jsonObject.getJSONArray("list").getJSONObject(i), goodsId);
            }
        }

    }

    private void renderItem(com.alibaba.fastjson.JSONObject item, String goodsId){
        if(item.getString("type").equals("goods")) {
            com.alibaba.fastjson.JSONObject options = item.getJSONObject("options");
            // 解析商品
            renderOptions(options, goodsId);
        }else if(item.getString("type").equals("menu")) {
            com.alibaba.fastjson.JSONObject options = item.getJSONObject("options");
            renderUrlOptions(options, goodsId);
        }
    }

    private void renderOptions(com.alibaba.fastjson.JSONObject options, String goodsId){
        String[] handlStrs = new String[]{"left", "middle", "right", "contentLeft", "contentRight"};

        String[] goodsStrs = new String[]{"goodsList", "listWay"};

        if (options.containsKey("list")) {
            JSONArray optionsListArray = options.getJSONArray("list");
            for (Object listObj : optionsListArray) {
                com.alibaba.fastjson.JSONObject listJson = (com.alibaba.fastjson.JSONObject) listObj;
                Arrays.stream(goodsStrs).forEach((str) -> {
                    listJson.forEach((key, value) -> {
                        if (key.equals(str)) {
                            JSONArray goodsListArray = listJson.getJSONArray(str);
                            JSONArray newGoodsListArray = new JSONArray();

                            goodsListArray.forEach(item -> {
                                com.alibaba.fastjson.JSONObject goodsJson = (com.alibaba.fastjson.JSONObject) item;
                                if (goodsJson.containsKey("url") &&
                                        goodsJson.getString("url").contains(goodsId)) {
                                    return;
                                }
                                if ((goodsJson.containsKey("goodsId") && goodsJson.getString("goodsId").contains(goodsId)) ||
                                        (goodsJson.containsKey("supplierGoodsId") && goodsJson.getString("supplierGoodsId").contains(goodsId))) {
                                    return;
                                }
                                newGoodsListArray.add(goodsJson);
                            });
                            listJson.put(str, newGoodsListArray);
                        }
                    });

                });
            }
        }

        Arrays.stream(handlStrs).forEach(str -> {
            if(options.containsKey(str)) {
                com.alibaba.fastjson.JSONObject jsonObj = options.getJSONObject(str);
                removeGoods(goodsId, jsonObj);
            }
        });
    }


    private void renderUrlOptions(com.alibaba.fastjson.JSONObject options, String goodsId){

        JSONArray array = options.getJSONArray("list");
        for (Object o : array) {
            com.alibaba.fastjson.JSONObject object = (com.alibaba.fastjson.JSONObject) o;
            if (object.containsKey("url")) {
                com.alibaba.fastjson.JSONObject urlJson = object.getJSONObject("url");
                if (urlJson.containsKey("pageData")) {
                    com.alibaba.fastjson.JSONObject pageData = urlJson.getJSONObject("pageData");
                    render(pageData, goodsId);
                    urlJson.put("pageData", pageData.toJSONString());
                }

            }
        }
    }

}
